package com.ylxin.smartplatform.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.socket.config.annotation.EnableWebSocket;

import javax.sql.DataSource;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 29048
 * @version V1.0
 * @Project smartplatform
 * @Package com.ylxin.smartplatform.config
 * @Description:  配置类 —— 约定优于配置
 * Create by 杨立新 @Date 2022/9/5 16:37
 */

@Configuration  //声明当前类是一个配置类，相当于代替了xml中的<beans>标签
@EnableTransactionManagement
@EnableAsync(proxyTargetClass = true)  //开启异步
@EnableWebSocket
public class BeanConfig {


    //<bean class="com.alibaba.druid.pool.DruidDataSource" id="datasource">
    //代替了<bean>标签，返回值的类型是bean 标签内的class,默认情况下，方法的名字就是 id
    //如果想要改变id ,可以在注解内声明新的id
    //@Bean("xindeid")
    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        //<property name="driverClassName" value="com.mysal.jdbc.Driver"/>
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        //<property nanme="url" value="jdbc:mysql://localhost:3306/smartformat?useUnicode=true&amp;characterEncoding=utf8"/>
        dataSource.setUrl("jdbc:mysql://localhost:3306/smartplatform?useUnicode=true&characterEncoding=utf8");
        //<property name="username" value="root"/>
        dataSource.setUsername("root");
        //<property nanme="password" value="root"/>
        dataSource.setPassword("root");
        return dataSource;
    }

    /**
     * 如果有参数，spring会查找自己管理的对象中有没有这个类型的对象，如果有就注入过来，形参的名字需要和想要引用对象的id保持一致。
     * @param dataSource
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        //设置分页插件   Interceptor  拦截
        sqlSessionFactoryBean.setPlugins(new PageInterceptor());
        //创建配置类
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        //设置 映射下划线为驼峰命名法
        configuration.setMapUnderscoreToCamelCase(true);
        //设置日志，日志中的类StdOutImpl 根据setLogImpl类中查找关键信息 log 取消全字匹配。
        configuration.setLogImpl(StdOutImpl.class);
        //设置配置
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean;
    }

    /**
     * 扫描 mapper
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.ylxin.smartplatform.mapper");
        return configurer;
    }

    /**
     * 平台事务 管理器
     * @param dataSource
     * @return
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

    /**
     * 线程池
     * @return
     */
    @Bean
    public TaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(15);
        executor.setMaxPoolSize(20);
        executor.setThreadNamePrefix("bk2205-");
        return executor;
    }

    @Bean
    public ObjectMapper objectMapper(){
        return new ObjectMapper();
    }


}
